home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 1 / Amiga Tools.iso / wb-tools / toolmanager / source / library / imageobj.c < prev    next >
C/C++ Source or Header  |  1994-06-06  |  14KB  |  437 lines

  1. /*
  2.  * imageobj.c  V2.1
  3.  *
  4.  * TMObject, Type: Image
  5.  *
  6.  * (c) 1990-1993 Stefan Becker
  7.  */
  8.  
  9. #include "ToolManagerLib.h"
  10.  
  11. /* extended TMTimerReq structure */
  12. struct TMTimerReqImage {
  13.                         struct TMTimerReq   tmtri_TimerReq;
  14.                         struct Image        tmtri_Image;
  15.                         struct TMImageNode *tmtri_NextImage;
  16.                        };
  17.  
  18. /* extended TMObject structure for TMOBJTYPE_Image objects */
  19. struct TMObjectImage {
  20.                       struct TMObject     io_Object;
  21.                       ULONG               io_Flags;
  22.                       char               *io_File;
  23.                       struct TMImageData *io_Data;
  24.                       UWORD               io_XSize;
  25.                       UWORD               io_YSize;
  26.                       struct Image       *io_Normal;
  27.                       struct Image       *io_Selected;
  28.                      };
  29.  
  30. /* io_Flags */
  31. #define IO_FreeData (1L<<0)
  32. #define IO_DiskObj  (1L<<1)
  33.  
  34. /* Data */
  35. static ULONG IconCount=0;
  36. struct Library *IconBase=NULL;
  37.  
  38. /* Try to open icon.library */
  39. static BOOL GetIconLibrary(void)
  40. {
  41.  /* Library already open or can we open it? */
  42.  if (IconBase || (IconBase=OpenLibrary("icon.library",37)))
  43.   {
  44.    /* Increment Icon counter */
  45.    IconCount++;
  46.  
  47.    /* All OK */
  48.    return(TRUE);
  49.   }
  50.  
  51.  /* Call failed */
  52.  return(FALSE);
  53. }
  54.  
  55. /* Try to close icon.library */
  56. static void FreeIconLibrary(void)
  57. {
  58.  /* Decrement Icon counter and close icon.library if zero */
  59.  if (--IconCount==0) {
  60.   CloseLibrary(IconBase);
  61.   IconBase=NULL;
  62.  }
  63. }
  64.  
  65. /* Create an Image object */
  66. struct TMObject *CreateTMObjectImage(struct TMHandle *handle, char *name,
  67.                                      struct TagItem *tags)
  68. {
  69.  struct TMObjectImage *tmobj;
  70.  
  71.  /* allocate memory for object */
  72.  if (tmobj=(struct TMObjectImage *)
  73.             AllocateTMObject(sizeof(struct TMObjectImage))) {
  74.   struct TagItem *ti,*tstate;
  75.  
  76.   /* Scan tag list */
  77.   tstate=tags;
  78.   while (ti=NextTagItem(&tstate)) {
  79.  
  80.    DEBUG_PRINTF("Got Tag (0x%08lx)\n",ti->ti_Tag);
  81.  
  82.    switch (ti->ti_Tag) {
  83.     case TMOP_File: tmobj->io_File=(char *) ti->ti_Data;
  84.                     break;
  85.     case TMOP_Data: tmobj->io_Data=(struct TMImageData *) ti->ti_Data;
  86.                     break;
  87.    }
  88.   }
  89.  
  90.   /* Sanity check */
  91.   if (!tmobj->io_File && !tmobj->io_Data) tmobj->io_File=DefaultNoName;
  92.  
  93.   /* File name supplied? */
  94.   if (tmobj->io_File) {
  95.    /* Yes. Read image data from it */
  96.    BPTR fl;
  97.  
  98.    /* Ignore user supplied data */
  99.    tmobj->io_Data=NULL;
  100.  
  101.    /* Try to open as IFF file first */
  102.    if (fl=Lock(tmobj->io_File,ACCESS_READ)) {
  103.     /* Got it. */
  104.     UnLock(fl);
  105.  
  106.     /* Read IFF file */
  107.     if (tmobj->io_Data=ReadIFFData(tmobj->io_File)) {
  108.      /* Got an IFF ILBM/ANIM */
  109.      struct Image *img=&tmobj->io_Data->tmid_Normal;
  110.  
  111.      tmobj->io_XSize=img->Width;
  112.      tmobj->io_YSize=img->Height+1;
  113.      tmobj->io_Normal=img;
  114.  
  115.      /* Get selected image */
  116.      img=&tmobj->io_Data->tmid_Selected;
  117.      if (img->ImageData)
  118.       tmobj->io_Selected=img;
  119.     }
  120.    }
  121.  
  122.    /* Got IFF data? No --> Open icon file */
  123.    if (!(tmobj->io_Data) && GetIconLibrary())
  124.     if (tmobj->io_Data=(struct TMImageData *) GetDiskObject(tmobj->io_File)) {
  125.      /* Got an icon */
  126.      struct Image *img=((struct DiskObject *) tmobj->io_Data)
  127.                         ->do_Gadget.GadgetRender;
  128.  
  129.      tmobj->io_Flags|=IO_DiskObj;
  130.      tmobj->io_XSize=img->Width;
  131.      tmobj->io_YSize=img->Height+1;
  132.      tmobj->io_Normal=img;
  133.      tmobj->io_Selected=((struct DiskObject *) tmobj->io_Data)
  134.                          ->do_Gadget.SelectRender;
  135.     }
  136.     else
  137.      FreeIconLibrary();
  138.  
  139.    /* All OK? */
  140.    if (tmobj->io_Data) {
  141.     tmobj->io_Flags|=IO_FreeData; /* Set free resources flag */
  142.     return(tmobj);
  143.    }
  144.   }
  145.   else {
  146.    /* No. User supplied image data directly */
  147.    struct Image *img=&tmobj->io_Data->tmid_Normal;
  148.  
  149.    tmobj->io_XSize=img->Width;
  150.    tmobj->io_YSize=img->Height+1;
  151.    tmobj->io_Normal=img;
  152.  
  153.    /* Get selected image */
  154.    img=&tmobj->io_Data->tmid_Selected;
  155.    if (img->ImageData)
  156.     tmobj->io_Selected=img;
  157.  
  158.    /* All OK */
  159.    return(tmobj);
  160.   }
  161.   FreeMem(tmobj,sizeof(struct TMObjectImage));
  162.  }
  163.  
  164.  /* call failed */
  165.  return(NULL);
  166. }
  167.  
  168. /* Delete an Image object */
  169. BOOL DeleteTMObjectImage(struct TMObjectImage *tmobj)
  170. {
  171.  DEBUG_PRINTF("Delete/Image (0x%08lx)\n",tmobj);
  172.  
  173.  /* Remove links */
  174.  DeleteAllLinksTMObject((struct TMObject *) tmobj);
  175.  
  176.  /* Remove object from list */
  177.  Remove((struct Node *) tmobj);
  178.  
  179.  /* Free resources? */
  180.  if (tmobj->io_Flags&IO_FreeData)
  181.   /* Yes, Icon file? */
  182.   if (tmobj->io_Flags&IO_DiskObj) {
  183.    /* Yes, release data */
  184.    FreeDiskObject((struct DiskObject *) tmobj->io_Data);
  185.    FreeIconLibrary();
  186.   }
  187.   else
  188.    /* No, IFF data -> release it */
  189.    FreeIFFData(tmobj->io_Data);
  190.  
  191.  /* Free object */
  192.  FreeMem(tmobj,sizeof(struct TMObjectImage));
  193.  
  194.  /* All OK. */
  195.  return(TRUE);
  196. }
  197.  
  198. /* Allocate & Initialize a TMLinkImage structure */
  199. struct TMLink *AllocLinkTMObjectImage(struct TMObjectImage *tmobj)
  200. {
  201.  struct TMLinkImage *tml;
  202.  
  203.  /* Allocate memory for link structure */
  204.  if (tml=AllocMem(sizeof(struct TMLinkImage),MEMF_CLEAR|MEMF_PUBLIC)) {
  205.   /* Initialize link structure */
  206.   tml->tmli_Link.tml_Size=sizeof(struct TMLinkImage);
  207.   tml->tmli_Width=tmobj->io_XSize;
  208.   tml->tmli_Height=tmobj->io_YSize;
  209.   tml->tmli_Normal=tmobj->io_Normal;
  210.   tml->tmli_Selected=tmobj->io_Selected;
  211.  }
  212.  
  213.  return(tml);
  214. }
  215.  
  216. /* Send timer request */
  217. static void SendTimerRequest(struct TMTimerReqImage *tmtri, BOOL last)
  218. {
  219.  struct timerequest *tr=&tmtri->tmtri_TimerReq.tmtr_Request;
  220.  
  221.  /* Initialize timer request */
  222.  tr->tr_node.io_Command=TR_ADDREQUEST;
  223.  tr->tr_time.tv_secs=last ? 1 : 0;
  224.  tr->tr_time.tv_micro=last ? 0 : 33333;
  225.  
  226.  /* Send timer request */
  227.  SendIO((struct IORequest *) tr);
  228. }
  229.  
  230. /* Abort timer request */
  231. static void AbortTimerRequest(struct TMTimerReqImage *tmtri)
  232. {
  233.  /* I/O request still active? */
  234.  if (!CheckIO((struct IORequest *) tmtri))
  235.   /* Yes. Abort it */
  236.   AbortIO((struct IORequest *) tmtri);
  237.  
  238.  /* Remove request from port */
  239.  WaitIO((struct IORequest *) tmtri);
  240. }
  241.  
  242. /* Activate an Image object */
  243. void ActivateTMObjectImage(struct TMLinkImage *tmli, void *start)
  244. {
  245.  struct TMObjectImage *tmobj=(struct TMObjectImage *)
  246.                               tmli->tmli_Link.tml_Linked;
  247.  UWORD x=tmli->tmli_LeftEdge;
  248.  UWORD y=tmli->tmli_TopEdge;
  249.  
  250.  DEBUG_PRINTF("Activate/Image (%ld)\n",start);
  251.  
  252.  /* Start animation? */
  253.  switch ((ULONG) start) {
  254.   case NULL:         {
  255.                       struct TMTimerReqImage *tmtri=tmli->tmli_Link.tml_Active;
  256.                       struct TMImageNode *tmin=tmtri->tmtri_NextImage;
  257.  
  258.                       /* Remove timer request */
  259.                       WaitIO((struct IORequest *) tmtri);
  260.  
  261.                       /* Draw next picture? */
  262.                       if (tmin) {
  263.                        /* Yes. Draw next picture */
  264.                        struct Image *img=&tmtri->tmtri_Image;
  265.  
  266.                        /* Set image pointer */
  267.                        img->ImageData=tmin->tmin_Data;
  268.  
  269.                        /* Draw picture */
  270.                        DrawImage(tmli->tmli_RastPort,img,x,y);
  271.  
  272.                        /* Set next picture */
  273.                        tmtri->tmtri_NextImage=tmin->tmin_Next;
  274.  
  275.                        /* Activate timer */
  276.                        SendTimerRequest(tmtri,tmtri->tmtri_NextImage==NULL);
  277.                       } else {
  278.                        /* No. Draw normal picture */
  279.                        DrawImage(tmli->tmli_RastPort,tmli->tmli_Normal,x,y);
  280.  
  281.                        /* Free timer request */
  282.                        FreeMem(tmtri,sizeof(struct TMTimerReqImage));
  283.                        tmli->tmli_Link.tml_Active=NULL;
  284.                       }
  285.                      }
  286.                      break;
  287.   case IOC_DEACTIVE: {
  288.                       struct TMTimerReqImage *tmtri=tmli->tmli_Link.tml_Active;
  289.  
  290.                       /* Anim active? */
  291.                       if (tmtri) {
  292.                        /* Yes. Stop it! Abort timer request */
  293.                        AbortTimerRequest(tmtri);
  294.  
  295.                        /* Free timer request */
  296.                        FreeMem(tmtri,sizeof(struct TMTimerReqImage));
  297.                        tmli->tmli_Link.tml_Active=NULL;
  298.                       }
  299.  
  300.                       /* Draw inactive image */
  301.                       DrawImage(tmli->tmli_RastPort,tmli->tmli_Normal,x,y);
  302.                      }
  303.                      break;
  304.   case IOC_ACTIVE:   {
  305.                       struct TMTimerReqImage *tmtri=tmli->tmli_Link.tml_Active;
  306.                       struct RastPort *rp=tmli->tmli_RastPort;
  307.  
  308.                       /* Anim active? */
  309.                       if (tmtri) {
  310.                        /* Yes. Stop it! Abort timer request */
  311.                        AbortTimerRequest(tmtri);
  312.  
  313.                        /* Draw inactive state */
  314.                        DrawImage(rp,tmli->tmli_Normal,x,y);
  315.  
  316.                        /* Free timer request */
  317.                        FreeMem(tmtri,sizeof(struct TMTimerReqImage));
  318.                        tmli->tmli_Link.tml_Active=NULL;
  319.                       }
  320.  
  321.                       /* Draw selected state. Got a selected image? */
  322.                       if (tmobj->io_Selected)
  323.                        /* Yes, draw it */
  324.                        DrawImage(rp,tmobj->io_Selected,x,y);
  325.                       else {
  326.                        /* No, invert image */
  327.                        SetDrMd(rp,COMPLEMENT);
  328.                        SetAPen(rp,0xff);
  329.                        RectFill(rp,x,y,x+tmobj->io_XSize-1,y+tmobj->io_YSize-2);
  330.                       }
  331.                      }
  332.                      break;
  333.   case IOC_FULLANIM: {
  334.                       struct TMTimerReqImage *tmtri=tmli->tmli_Link.tml_Active;
  335.                       struct RastPort *rp=tmli->tmli_RastPort;
  336.  
  337.                       /* Anim active? */
  338.                       if (tmtri) {
  339.                        /* Yes. Stop it! Abort timer request */
  340.                        AbortTimerRequest(tmtri);
  341.  
  342.                        /* Draw inactive state */
  343.                        DrawImage(rp,tmli->tmli_Normal,x,y);
  344.  
  345.                        /* Free timer request */
  346.                        FreeMem(tmtri,sizeof(struct TMTimerReqImage));
  347.                        tmli->tmli_Link.tml_Active=NULL;
  348.                       }
  349.  
  350.                       /* Start animation after 1st image. Get memory. */
  351.                       if (tmtri=AllocMem(sizeof(struct TMTimerReqImage),
  352.                                          MEMF_PUBLIC)) {
  353.                        /* Got it */
  354.                        struct Image *img=tmobj->io_Selected;
  355.  
  356.                        /* Init timer request */
  357.                        tmtri->tmtri_TimerReq.tmtr_Request=*deftimereq;
  358.                        tmtri->tmtri_Image=*(tmli->tmli_Normal);
  359.                        tmtri->tmtri_TimerReq.tmtr_Link=(struct TMLink *) tmli;
  360.  
  361.                        /* No icon file and more than one picture? */
  362.                        if (!(tmobj->io_Flags & IO_DiskObj) && img)
  363.                         /* Yes. Set anim starting image */
  364.                         tmtri->tmtri_NextImage=tmobj->io_Data->tmid_Data->
  365.                                                 tmin_Next->tmin_Next;
  366.                        else
  367.                         /* Only one picture animation */
  368.                         tmtri->tmtri_NextImage=NULL;
  369.  
  370.                        /* Got a second picture? */
  371.                        if (img)
  372.                         /* Yes, draw it */
  373.                         DrawImage(rp,img,x,y);
  374.                        else {
  375.                         /* No, invert image */
  376.                         SetDrMd(rp,COMPLEMENT);
  377.                         SetAPen(rp,0xff);
  378.                         RectFill(rp,x,y,x+tmobj->io_XSize-1,
  379.                                  y+tmobj->io_YSize-2);
  380.                        }
  381.  
  382.                        /* Send timer request */
  383.                        SendTimerRequest(tmtri,FALSE);
  384.  
  385.                        /* Set active flag */
  386.                        tmli->tmli_Link.tml_Active=tmtri;
  387.                       }
  388.                      }
  389.                      break;
  390.   case IOC_CONTANIM: {
  391.                       struct TMTimerReqImage *tmtri=tmli->tmli_Link.tml_Active;
  392.  
  393.                       /* Anim active? */
  394.                       if (tmtri) {
  395.                        /* Yes. Stop it! Abort timer request */
  396.                        AbortTimerRequest(tmtri);
  397.  
  398.                        /* Free timer request */
  399.                        FreeMem(tmtri,sizeof(struct TMTimerReqImage));
  400.                        tmli->tmli_Link.tml_Active=NULL;
  401.                       }
  402.  
  403.                       /* Start animation after 2nd image */
  404.                       /* Icon file or only one picture? */
  405.                       if ((tmobj->io_Flags & IO_DiskObj) ||
  406.                           !tmobj->io_Selected)
  407.                        /* Yes. Draw normal state */
  408.                        DrawImage(tmli->tmli_RastPort,tmli->tmli_Normal,x,y);
  409.                       else {
  410.                        struct TMImageNode *tmin=tmobj->io_Data->tmid_Data->
  411.                                                  tmin_Next->tmin_Next;
  412.  
  413.                        /* Got more than 2 images and can we allocate memory */
  414.                        /* for timer request? */
  415.                        if (tmin && (tmtri=AllocMem(
  416.                                            sizeof(struct TMTimerReqImage),
  417.                                            MEMF_PUBLIC))) {
  418.                         /* Yes, start anim. Init timer request */
  419.                         tmtri->tmtri_TimerReq.tmtr_Request=*deftimereq;
  420.                         tmtri->tmtri_Image=*(tmli->tmli_Normal);
  421.                         tmtri->tmtri_TimerReq.tmtr_Link=(struct TMLink *) tmli;
  422.                         tmtri->tmtri_NextImage=tmin;
  423.  
  424.                         /* Send timer request */
  425.                         SendTimerRequest(tmtri,FALSE);
  426.  
  427.                         /* Set active flag */
  428.                         tmli->tmli_Link.tml_Active=tmtri;
  429.                        } else
  430.                         /* No. Draw normal state */
  431.                         DrawImage(tmli->tmli_RastPort,tmli->tmli_Normal,x,y);
  432.                       }
  433.                      }
  434.                      break;
  435.  }
  436. }
  437.